﻿/**
 * Copyright(c) Live2D Inc. All rights reserved.
 *
 * Use of this source code is governed by the Live2D Open Software license
 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
 */

#pragma once

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "../include/Live2dAllocator.hpp"
#include "../include/Live2dDefine.hpp"
#include "../include/catlive2d.hpp"

class Live2dView;
class Live2dTextureManager;

/**
* @brief   アプリケーションクラス。
*   Cubism SDK の管理を行う。
*/
class Live2dDelegate
{
public:
    /**
    * @brief   クラスのインスタンス（シングルトン）を返す。<br>
    *           インスタンスが生成されていない場合は内部でインスタンを生成する。
    *
    * @return  クラスのインスタンス
    */
    static Live2dDelegate* GetInstance();

    /**
    * @brief   クラスのインスタンス（シングルトン）を解放する。
    *
    */
    static void ReleaseInstance();

    /**
    * @brief   APPに必要なものを初期化する。
    */
    bool Initialize();

    /**
   * @brief   检查是否初始化
   */
    bool IsInitialize();

    /**
    * @brief   解放する。
    */
    void Release();

    /**
    * @brief   実行処理。
    */
    void Run(void* texture);

    /**
    * @brief   重新设置窗口大小。
    */
    bool Resize(int width, int height);

    /**
    * @brief   伸缩窗口大小。
    */
    bool Scale(float s_x, float s_y);

    /**
    * @brief    变换窗口位置。
    */
    bool Translate(float t_x, float t_y);

    /**
    * @brief   加载模型文件
    */
    bool LoadModelFromFile(const char* dir, const char* fileName);

    void ReleaseModel();

    /**
    * @brief   鼠标点击回调函数
    */
    void OnMouseClickCallBack(const cat_mouse_click_event* event, bool mouse_up);

    /**
    * @brief  鼠标移动回调函数
    */
    void OnMouseMoveCallBack(float m_x, float m_y);


    void OnLeftHandDownCallBack(bool key_up);


    void OnRightHandDownCallBack(bool key_up);

    /************************joystick*****************************/

    void OnStickLeftDownCallBack(bool key_up);

    void OnStickRightDownCallBack(bool key_up);

    void OnStickShowLeftHandCallBack(bool key_up);

    void OnStickShowRightHandCallBack(bool key_up);

    void OnStickLCallBack(float x, float y);

    void OnStickRCallBack(float x, float y);

    /*************************************************************/

    void StartMotion(const char* group, const int id);

    void StartExpression(const char* expressionId);

    void StartExpressionById(const int id);

    void SetSpeed(const float speed);

    void SetRandomMotion(const bool random, const bool randomExpression);

    /**
   * @brief   Window情報を取得する。
   */
    GLFWwindow* GetWindow() { return _window; }
    /**
    * @brief   View情報を取得する。
    */
    Live2dView* GetView() { return _view; }

    Live2dTextureManager* GetTextureManager() { return _textureManager; }
    
    /**
    * @brief シェーダーを登録する。
    */
    GLuint CreateShader();

private:

    Live2dDelegate();

    ~Live2dDelegate();

    void InitializeCubism();

    Live2dAllocator _cubismAllocator;              ///< Cubism SDK Allocator
    Csm::CubismFramework::Option _cubismOption;  ///< Cubism SDK Option
    GLFWwindow* _window;                         ///< OpenGL ウィンドウ
    Live2dView* _view;                             ///< View情報
    Live2dTextureManager* _textureManager;         ///< テクスチャマネージャー

    bool isInit;                                 ///< 是否初始化
     /**
     * @brief   CreateShader内部関数 エラーチェック
     */
    bool CheckShader(GLuint shaderId);
};


